﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
using Entidad;

public enum Acciones { agregar, actualizar, eliminar, nada };

namespace DAO
{
    public class RestauracionDAO : RestauracionInterface
    {
        static DAO_v2 dao = new DAO_v2();
        public List<RestauracionQuery> ObtenerRestauraciones(int codEjemplar)
        {
            SqlConnection con = new SqlConnection(DAO_v2.MiCadenaConexion());
            List<RestauracionQuery> resultado;
            try
            {
                con.Open();
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = con;
                cmd.CommandType = System.Data.CommandType.Text;
                String consulta = "SELECT id_Restauracion, numero, fechaInicio, fechaEntrega, costo, descripcion, codigo ";
                consulta += "FROM Restauracion LEFT JOIN ";
                consulta += "Ejemplar ON Restauracion.id_Ejemplar = Ejemplar.id_Ejemplar ";
                consulta += "WHERE Ejemplar.codigo = @codigo";
                cmd.Parameters.AddWithValue("@codigo", codEjemplar);
                cmd.CommandText = consulta;
                resultado = new List<RestauracionQuery>();
                SqlDataReader dr = cmd.ExecuteReader();
                while (dr.Read())
                {
                    RestauracionQuery restauracion = new RestauracionQuery();
                    restauracion.IdRestauracion = int.Parse(dr["id_Restauracion"].ToString());
                    restauracion.Numero = int.Parse(dr["numero"].ToString());
                    restauracion.FechaInicio = DateTime.Parse(dr["fechaInicio"].ToString());
                    if (dr["fechaEntrega"] != DBNull.Value)
                    {
                        restauracion.FechaEntrega = DateTime.Parse(dr["fechaEntrega"].ToString());
                    }
                    restauracion.Costo = decimal.Round(decimal.Parse(dr["costo"].ToString()), 2);
                    if (dr["descripcion"] != DBNull.Value)
                    {
                        restauracion.Descripcion = dr["descripcion"].ToString();
                    }
                    restauracion.CodigoEjemplar = int.Parse(dr["codigo"].ToString());
                    resultado.Add(restauracion);
                }
                dr.Close();
                return resultado;
            }
            catch (SqlException)
            {
                return null;
                throw new ApplicationException("Error al obtener las restauraciones del ejemplar");
            }
            finally
            {
                dao.CerrarConexion(con);
            }
        }

        public int? ObtenerNumeroUltima(int codEjemplar)
        {
            SqlConnection con = new SqlConnection(DAO_v2.MiCadenaConexion());
            try
            {
                con.Open();
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = con;
                cmd.CommandType = System.Data.CommandType.Text;
                String comando = "SELECT TOP 1 numero ";
                comando += "FROM Restauracion RIGHT JOIN ";
                comando += "Ejemplar ON Restauracion.id_Ejemplar = Ejemplar.id_Ejemplar ";
                comando += "WHERE Ejemplar.codigo = @Codigo ";
                comando += "ORDER BY numero DESC ";
                cmd.Parameters.AddWithValue("@Codigo", codEjemplar);
                cmd.CommandText = comando;
                int resultado;
                object res = cmd.ExecuteScalar();
                if (res != DBNull.Value)
                {
                    resultado = (int)res;
                }
                else
                {
                    resultado = 0;
                }
                return resultado;
            }
            catch (SqlException)
            {
                return null;
                throw new ApplicationException("Error al obtener el numero de la ultima restauracion");
            }
            finally
            {
                if (con.State == System.Data.ConnectionState.Open)
                {
                    con.Close();
                }
            }
        }

        public RestauracionEnt ObtenerRestauracion(int numero, int codigo)
        {
            SqlConnection con = new SqlConnection(DAO_v2.MiCadenaConexion());
            try
            {
                con.Open();
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = con;
                String consulta = "SELECT ";
                consulta += "R.id_Restauracion, R.id_Restaurador, R.id_HistorialRestauracion, R.id_Ejemplar, R.numero, R.fechaInicio, R.fechaEntrega, R.costo, R.descripcion ";
                consulta += "FROM Restauracion R ";
                consulta += "LEFT JOIN Ejemplar E ON R.id_Ejemplar = E.id_Ejemplar ";
                consulta += "WHERE 1 = 1 ";
                consulta += "AND R.numero = @numero ";
                consulta += "AND E.codigo = @codigo ";
                cmd.Parameters.AddWithValue("@numero", numero);
                cmd.Parameters.AddWithValue("@codigo", codigo);
                cmd.CommandText = consulta;
                SqlDataReader dr = cmd.ExecuteReader();
                RestauracionEnt resultado = null;
                while (dr.Read())
                {
                    resultado = new RestauracionEnt();
                    resultado.IdRestauracion = int.Parse(dr["id_Restauracion"].ToString());
                    resultado.IdRestaurador = int.Parse(dr["id_Restaurador"].ToString());
                    resultado.Id_HistorialRestauracion = int.Parse(dr["id_HistorialRestauracion"].ToString());
                    resultado.IdEjemplar = int.Parse(dr["id_Ejemplar"].ToString());
                    resultado.Numero = int.Parse(dr["numero"].ToString());
                    resultado.FechaInicio = DateTime.Parse(dr["fechaInicio"].ToString());
                    if (dr["fechaEntrega"] != DBNull.Value)
                    {
                        resultado.FechaEntrega = DateTime.Parse(dr["fechaEntrega"].ToString());
                    }
                    resultado.Costo = decimal.Parse(dr["costo"].ToString());
                    if (dr["descripcion"] != DBNull.Value)
                    {
                        resultado.Descripcion = dr["descripcion"].ToString();
                    }
                }
                dr.Close();
                return resultado;
            }
            catch (SqlException)
            {
                return null;
                throw new ApplicationException("Error al obtener la restauracion");
            }
            finally
            {
                if (con.State == System.Data.ConnectionState.Open)
                {
                    con.Close();
                }
            }
        }

        public RestauracionEnt ObtenerRestauracion(int codigo)
        {
            SqlConnection con = new SqlConnection(DAO_v2.MiCadenaConexion());
            try
            {
                con.Open();
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = con;
                String consulta = "SELECT ";
                consulta += "R.id_Restauracion, R.id_Restaurador, R.id_HistorialRestauracion, R.id_Ejemplar, R.numero, R.fechaInicio, R.fechaEntrega, R.costo, R.descripcion ";
                consulta += "FROM Restauracion R ";
                consulta += "LEFT JOIN Ejemplar E ON R.id_Ejemplar = E.id_Ejemplar ";
                consulta += "WHERE 1 = 1 ";
                consulta += "AND E.codigo = @codigo ";
 
                cmd.Parameters.AddWithValue("@codigo", codigo);
                cmd.CommandText = consulta;
                SqlDataReader dr = cmd.ExecuteReader();
                RestauracionEnt resultado = null;
                while (dr.Read())
                {
                    resultado = new RestauracionEnt();
                    resultado.IdRestauracion = int.Parse(dr["id_Restauracion"].ToString());
                    resultado.IdRestaurador = int.Parse(dr["id_Restaurador"].ToString());
                    resultado.Id_HistorialRestauracion = int.Parse(dr["id_HistorialRestauracion"].ToString());
                    resultado.IdEjemplar = int.Parse(dr["id_Ejemplar"].ToString());
                    resultado.Numero = int.Parse(dr["numero"].ToString());
                    resultado.FechaInicio = DateTime.Parse(dr["fechaInicio"].ToString());
                    if (dr["fechaEntrega"] != DBNull.Value)
                    {
                        resultado.FechaEntrega = DateTime.Parse(dr["fechaEntrega"].ToString());
                    }
                    resultado.Costo = decimal.Parse(dr["costo"].ToString());
                    if (dr["descripcion"] != DBNull.Value)
                    {
                        resultado.Descripcion = dr["descripcion"].ToString();
                    }
                }
                dr.Close();
                return resultado;
            }
            catch (SqlException)
            {
                return null;
                throw new ApplicationException("Error al obtener la restauracion");
            }
            finally
            {
                if (con.State == System.Data.ConnectionState.Open)
                {
                    con.Close();
                }
            }
        }

        public void ActualizarRestauracion(RestauracionEnt restauracion, List<DetalleRestauracionEnt> agregar, List<DetalleRestauracionEnt> eliminar, List<DetalleRestauracionEnt> actualizar)
        {
            SqlConnection con = new SqlConnection(DAO_v2.MiCadenaConexion());
            DetalleRestauracionDAO drDAO = new DetalleRestauracionDAO();
            SqlTransaction tran = null;
            try
            {
                con.Open();
                tran = con.BeginTransaction();
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = con;
                cmd.Transaction = tran;
                String consulta = "UPDATE Restauracion ";
                consulta += "SET ";
                consulta += "fechaInicio = @fechaInicio, fechaEntrega = @fechaEntrega, costo = @costo, descripcion = @descripcion, id_Restaurador = @id_Restaurador ";
                consulta += "WHERE numero = @numero ";
                cmd.Parameters.AddWithValue("@fechaInicio", restauracion.FechaInicio);
                cmd.Parameters.AddWithValue("@fechaEntrega", restauracion.FechaEntrega);
                cmd.Parameters.AddWithValue("@costo", restauracion.Costo);
                cmd.Parameters.AddWithValue("@descripcion", restauracion.Descripcion);
                cmd.Parameters.AddWithValue("@id_Restaurador", restauracion.IdRestaurador);
                cmd.Parameters.AddWithValue("@numero", restauracion.Numero);
                cmd.CommandText = consulta;
                cmd.ExecuteNonQuery();
                foreach (DetalleRestauracionEnt dAgregar in agregar)
                {
                    drDAO.GuardarDetalle(dAgregar, tran, restauracion.IdRestauracion.Value, con);
                }
                foreach (DetalleRestauracionEnt dEliminar in eliminar)
                {
                    drDAO.EliminarDetalle(dEliminar,tran,con);
                }
                foreach (DetalleRestauracionEnt dActualizar in actualizar)
                {
                    drDAO.ActualizarDetalle(dActualizar,tran,con);
                }
                tran.Commit();
            }
            catch (SqlException)
            {
                tran.Rollback();
                throw new ApplicationException("Error al actualizar la restauracion");
            }
            finally
            {
                if (con.State == System.Data.ConnectionState.Open)
                {
                    con.Close();
                }
            }
        }

        public bool GuardarRestauracion(RestauracionEnt restauracion, List<DetalleRestauracionEnt> detalles)
        {
            SqlConnection con = new SqlConnection(DAO_v2.MiCadenaConexion());
            SqlTransaction tran = null;
            try
            {
                con.Open();
                tran = con.BeginTransaction();
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = con;
                cmd.Transaction = tran;

                //Compruebo si existe un historial, si no existe, lo creo
                int id_HistorialRestauracion;
                HistorialRestauracionDAO historialDAO = new HistorialRestauracionDAO();
                DetalleRestauracionDAO detalleDAO = new DetalleRestauracionDAO();
                HistorialRestauracionEnt historial = historialDAO.ObtenerHistorial(restauracion.IdEjemplar,tran, con);
                if(historial != null)
                {
                    id_HistorialRestauracion = int.Parse(historial.ID_HistorialRestauracion.ToString());
                }
                else
                {
                    id_HistorialRestauracion = historialDAO.CrearHistorial(restauracion.IdEjemplar);
                }
               

                //Grabo la Restauracion
                String consulta = "INSERT INTO Restauracion " ;
                consulta += "(id_Restaurador, id_HistorialRestauracion, id_Ejemplar, numero, fechaInicio, fechaEntrega, costo, descripcion) ";
                consulta += "VALUES (@id_Restaurador, @id_HistorialRestauracion, @id_Ejemplar, @numero, @fechaInicio, @fechaEntrega, @costo, @descripcion); SELECT @@IDENTITY";
                cmd.Parameters.AddWithValue("@id_Restaurador",restauracion.IdRestaurador);
                cmd.Parameters.AddWithValue("@id_HistorialRestauracion",id_HistorialRestauracion);
                cmd.Parameters.AddWithValue("@id_Ejemplar", restauracion.IdEjemplar);
                cmd.Parameters.AddWithValue("@numero",restauracion.Numero);
                cmd.Parameters.AddWithValue("@fechaInicio",restauracion.FechaInicio);
                if (restauracion.FechaEntrega.HasValue)
                {
                    cmd.Parameters.AddWithValue("@fechaEntrega", restauracion.FechaEntrega);
                }
                else
                {
                    cmd.Parameters.AddWithValue("@fechaEntrega", DBNull.Value);
                }
                cmd.Parameters.AddWithValue("@costo",restauracion.Costo);
                if (restauracion.Descripcion != null)
                {
                    cmd.Parameters.AddWithValue("@descripcion", restauracion.Descripcion);
                }
                else
                {
                    cmd.Parameters.AddWithValue("@descripcion", DBNull.Value);
                }
                cmd.CommandText = consulta;
                int id_Restauracion = int.Parse(cmd.ExecuteScalar().ToString());

                //Grabo los detalles
                foreach (DetalleRestauracionEnt detalle in detalles)
                {
                    detalleDAO.GuardarDetalle(detalle,tran,id_Restauracion,con);
                }

                //Actualizo el historial
                historialDAO.Actualizar(id_HistorialRestauracion, tran, id_Restauracion,con);
                tran.Commit();

                return true;
            }
            catch (SqlException)
            {
                tran.Rollback();
                return false;
                throw new ApplicationException();
            }
            finally
            {
                if (con.State == System.Data.ConnectionState.Open)
                {
                    con.Close();
                }
            }
        }
        



        //Implementaciones de interface
        public List<DetalleRestauracionEnt> ObtenerDetalles(int restauracion, int ejemplar)
        {
            throw new NotImplementedException();
        }

        public List<TipoRestauracionEnt> ObtenerTiposRestauracion()
        {
            throw new NotImplementedException();
        }

        public List<EjemplarBusquedaQueryEnt> BuscarEjemplares(List<string> filtros)
        {
            throw new NotImplementedException();
        }
    }
}
